﻿/// <reference path="../../../../SIR.Web/scripts/_references.js" />
/// <reference path="../../../../SIR.Web/scripts/jquery-1.9.1.js" />
/// <reference path="../../../../SIR.Web/scripts/angular.js" />
/// <reference path="../../../../SIR.Web/scripts/angular-mocks.js" />
/// <reference path="../../../../SIR.Web/scripts/modal.js" />

/// <reference path="../../../../SIR.Web/app/app.js" />
/// <reference path="../../../../SIR.Web/app/common/common.js" />
/// <reference path="../../../../SIR.Web.Tests/JavaScript/sir-mock.js" />
/// <reference path="../../../../SIR.Web/app/search/search.js" />
/// <reference path="../../../../SIR.Web/app/user/user.js" />
/// <reference path="../../../../SIR.Web/app/authenticate/authenticate.js" />
/// <reference path="../../../../SIR.Web/app/authenticate/services/auth-service.js" />
/// <reference path="../../../../SIR.Web/app/common/services/data-service.js" />
/// <reference path="../../../../SIR.Web/app/search/controllers/search-controller.js" />
/// <reference path="../../../../SIR.Web/app/search/controllers/search-results-container-controller.js" />
/// <reference path="../../../../SIR.Web/app/search/controllers/search-results-by-image-controller.js" />
/// <reference path="../../../../SIR.Web/app/search/controllers/search-results-by-pattern-controller.js" />
/// <reference path="../../../../SIR.Web/app/search/controllers/search-results-by-colors-controller.js" />


describe('Web Interfaces: ', function () {
	'use strict';
	// initialize variables and modules
	var searchScope, resultsScope, searchController,
		resultsContainerController, resultsController, rootScope,
    	mockUploadService, mockDataService;

	beforeEach(module('ui.router'));
	beforeEach(module('ui.bootstrap.modal'));
	beforeEach(module('app.common'));
	beforeEach(module('app.search'));
	beforeEach(module('app.authenticate'));

	beforeEach(inject(function ($controller, $rootScope) {
		// set the root scope
		rootScope = $rootScope;
		// create the mock data service
		mockDataService = {
			download: function () {
				return {
					then: function (callback) {
						callback({ data: { Successful: true, Content: [{}] } });
					}
				};
			}
		};
		// create the search scope
		searchScope = $rootScope.$new();
		// create search controller
		searchController = $controller('SearchController', {
			$scope: searchScope,
			$state: {},
			uploadService: mockUploadService,
			dataService: mockDataService
		});
		// create the results scope
		resultsScope = $rootScope.$new();
		// create the results container controller with the results scope
		resultsContainerController = $controller('SearchResultsContainerController', {
			$scope: resultsScope
		});

	}));

	describe('Search - No Results (Total: 3)', function () {
		it('[1] Produce \'No Results\' message with an all white image input', function () {

			inject(function ($controller) {
				// create the inner results controller for search by image
				resultsController = $controller('SearchResultsByImageController', {
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// create the search service to return no results
					searchService: {
						byImage: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify loading complete
			expect(resultsScope.loading).toBeFalsy();
			// verify no images
			expect(resultsScope.hasResults).toBeFalsy();
			// verify message is empty
			expect(resultsScope.message).toBe('');
		});

		it('[2] Produce \'No Results\' message with color balance criteria specifying an all-white image input', function () {
			inject(function ($controller) {
				// create the search by colors controller
				resultsController = $controller('SearchResultsByColorsController', {
					// use the results scope
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// create the search service to return no results
					searchService: {
						byColors: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify loading complete
			expect(resultsScope.loading).toBeFalsy();
			// verify no images
			expect(resultsScope.hasResults).toBeFalsy();
			// verify message is empty
			expect(resultsScope.message).toBe('');
		});

		it('[3] Produce \'No Results\' message with any pattern option available input', function () {
			inject(function ($controller) {
				resultsController = $controller('SearchResultsByPatternController', {
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							patternId: 0
						}
					},
					dataService: {
						download: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [], Message: '' } });
								}
							}
						}
					},
					// configure search service to return no results
					searchService: {
						byPattern: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [], Message: '' } });
								}
							}
						}
					}
				});
			});

			// verify loading complete
			expect(resultsScope.loading).toBeFalsy();
			// verify no images
			expect(resultsScope.hasResults).toBeFalsy();
			// verify message is empty
			expect(resultsScope.message).toBe('');
		});
	});

	describe('Search - Error (Total: 3)', function () {
		it('[1] Produce \'Error\' message with an invalid image input', function () {
			inject(function ($controller) {
				// create the inner controller for the search by image results
				resultsController = $controller('SearchResultsByImageController', {
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// configure search service to return an error
					searchService: {
						byImage: function () {
							return {
								then: function (callback) {
									callback({
										data: {
											Successful: true,
											Content: [],
											Message: 'There was no image found with the ID of -1'
										}
									});
								}
							}
						}
					}
				});
			});
			// verify loading complete
			expect(resultsScope.loading).toBeFalsy();
			// verify no images
			expect(resultsScope.hasResults).toBeFalsy();
			// verify exception message
			expect(resultsScope.message).toBe('There was no image found with the ID of -1');
		});

		it('[2] Produce \'Error\' message with an invalid set of color balance criteria input', function () {
			inject(function ($controller) {
				// create the search by colors controller
				resultsController = $controller('SearchResultsByColorsController', {
					// use the results scope
					$scope: resultsScope,
					// create the search parameters
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// configure search service to return an error
					searchService: {
						byColors: function () {
							return {
								then: function (callback) {
									callback({
										data: {
											Successful: true,
											Content: [],
											Message: 'Invalid color definitions'
										}
									});
								}
							}
						}
					}
				});
			});
			// verify loading complete
			expect(resultsScope.loading).toBeFalsy();
			// verify no images
			expect(resultsScope.hasResults).toBeFalsy();
			// verify exception message
			expect(resultsScope.message).toBe('Invalid color definitions');
		});

		it('[3] Produce \'Error\' message with an invalid pattern that does not exist input', function () {
			inject(function ($controller) {
				resultsController = $controller('SearchResultsByPatternController', {
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							patternId: 0
						}
					},
					// configure data service to return no data
					dataService: {
						download: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [], Message: '' } });
								}
							}
						}
					},
					// configure search service to return the error
					searchService: {
						byPattern: function () {
							return {
								then: function (callback) {
									callback({
										data: {
											Successful: true,
											Content: [],
											Message: 'There was no pattern found with the ID of -1'
										}
									});
								}
							}
						}
					}
				});
			});
			// verify loading complete
			expect(resultsScope.loading).toBeFalsy();
			// verify no images
			expect(resultsScope.hasResults).toBeFalsy();
			// verify exception message
			expect(resultsScope.message).toBe('There was no pattern found with the ID of -1');
		});
	});

	describe('Search - By Image (Total: 3)', function () {
		it('[1] Produce \'10 Image\' results with an image of a beach as input', function () {
			inject(function ($controller) {
				// create the inner results controller for search by image
				resultsController = $controller('SearchResultsByImageController', {
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// configure search service to return 10 images
					searchService: {
						byImage: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify no longer loading
			expect(resultsScope.loading).toBeFalsy();
			// verify results is true
			expect(resultsScope.hasResults).toBeTruthy();
			// verify 10 results
			expect(resultsScope.images.items.length).toBe(10);
			// verify empty message
			expect(resultsScope.message).toBe('');
		});

		it('[2] Produce \'10 Image\' results with an image of a forest as input', function () {
			inject(function ($controller) {
				// create the inner results controller for search by image
				resultsController = $controller('SearchResultsByImageController', {
					$scope: resultsScope,
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// configure search service to return 10 images
					searchService: {
						byImage: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify no longer loading
			expect(resultsScope.loading).toBeFalsy();
			// verify results is true
			expect(resultsScope.hasResults).toBeTruthy();
			// verify 10 results
			expect(resultsScope.images.items.length).toBe(10);
			// verify empty message
			expect(resultsScope.message).toBe('');
		});

		it('[3] Produce \'10 Image\' results with an image of a sunset as input', function () {
			inject(function ($controller) {
				// create the inner results controller for search by image
				resultsController = $controller('SearchResultsByImageController', {
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// configure search service to return 10 images
					searchService: {
						byImage: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify no longer loading
			expect(resultsScope.loading).toBeFalsy();
			// verify results is true
			expect(resultsScope.hasResults).toBeTruthy();
			// verify 10 results
			expect(resultsScope.images.items.length).toBe(10);
			// verify empty message
			expect(resultsScope.message).toBe('');
		});
	});

	describe('Search - By Color Balance (Total: 3)', function () {
		it('[1] Produce \'10 Image\' results of a pattern with a darker top and bottom and a lighter center as input', function () {
			inject(function ($controller) {
				// create the search by colors controller
				resultsController = $controller('SearchResultsByColorsController', {
					// use the results scope
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// configure search service to return 10 images
					searchService: {
						byColors: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify no longer loading
			expect(resultsScope.loading).toBeFalsy();
			// verify results is true
			expect(resultsScope.hasResults).toBeTruthy();
			// verify 10 results
			expect(resultsScope.images.items.length).toBe(10);
			// verify empty message
			expect(resultsScope.message).toBe('');
		});

		it('[2] Produce \'10 Image\' results of a pattern with a darker center and lighter top and bottom as input', function () {
			inject(function ($controller) {
				// create the search by colors controller
				resultsController = $controller('SearchResultsByColorsController', {
					// use the results scope
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// configure search service to return 10 images
					searchService: {
						byColors: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify no longer loading
			expect(resultsScope.loading).toBeFalsy();
			// verify results is true
			expect(resultsScope.hasResults).toBeTruthy();
			// verify 10 results
			expect(resultsScope.images.items.length).toBe(10);
			// verify empty message
			expect(resultsScope.message).toBe('');
		});

		it('[3] Produce \'10 Image\' results of a pattern with alternating dark and light vertical stripes as input', function () {
			inject(function ($controller) {
				// create the search by colors controller
				resultsController = $controller('SearchResultsByColorsController', {
					// use the results scope
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							imageId: 0
						}
					},
					// configure search service to return 10 images
					searchService: {
						byColors: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify no longer loading
			expect(resultsScope.loading).toBeFalsy();
			// verify results is true
			expect(resultsScope.hasResults).toBeTruthy();
			// verify 10 results
			expect(resultsScope.images.items.length).toBe(10);
			// verify empty message
			expect(resultsScope.message).toBe('');
		});
	});

	describe('Search - By Pattern (Total: 3)', function () {
		it('[1] Produce \'10 Image\' results of a pattern with a darker top and bottom and a lighter center as input', function () {
			inject(function ($controller) {
				// create results controller with the search by pattern controller
				resultsController = $controller('SearchResultsByPatternController', {
					// use the results scope
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							patternId: 0
						}
					},
					// configure data service to download nothing but be successful
					dataService: {
						download: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [], Message: '' } });
								}
							}
						}
					},
					// configure search service to return 10 results
					searchService: {
						byPattern: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify no longer loading
			expect(resultsScope.loading).toBeFalsy();
			// verify results is true
			expect(resultsScope.hasResults).toBeTruthy();
			// verify 10 results
			expect(resultsScope.images.items.length).toBe(10);
			// verify empty message
			expect(resultsScope.message).toBe('');
		});

		it('[2] Produce \'10 Image\' results of a pattern with a darker center and lighter top and bottom as input', function () {
			inject(function ($controller) {
				// create results controller with the search by pattern controller
				resultsController = $controller('SearchResultsByPatternController', {
					// use the results scope
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							patternId: 0
						}
					},
					// configure data service to download nothing but be successful
					dataService: {
						download: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [], Message: '' } });
								}
							}
						}
					},
					// configure search service to return 10 results
					searchService: {
						byPattern: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify no longer loading
			expect(resultsScope.loading).toBeFalsy();
			// verify results is true
			expect(resultsScope.hasResults).toBeTruthy();
			// verify 10 results
			expect(resultsScope.images.items.length).toBe(10);
			// verify empty message
			expect(resultsScope.message).toBe('');
		});

		it('[3] Produce \'10 Image\' results of a pattern with alternating dark and light vertical stripes as input', function () {
			inject(function ($controller) {
				// create results controller with the search by pattern controller
				resultsController = $controller('SearchResultsByPatternController', {
					// use the results scope
					$scope: resultsScope,
					// set the search parameters
					$state: {
						params: {
							tolerance: 0,
							patternId: 0
						}
					},
					// configure data service to download nothing but be successful
					dataService: {
						download: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [], Message: '' } });
								}
							}
						}
					},
					// configure search service to return 10 results
					searchService: {
						byPattern: function () {
							return {
								then: function (callback) {
									callback({ data: { Successful: true, Content: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], Message: '' } });
								}
							}
						}
					}
				});
			});
			// verify no longer loading
			expect(resultsScope.loading).toBeFalsy();
			// verify results is true
			expect(resultsScope.hasResults).toBeTruthy();
			// verify 10 results
			expect(resultsScope.images.items.length).toBe(10);
			// verify empty message
			expect(resultsScope.message).toBe('');
		});
	});
});